import Vue from 'vue'

const debounce = (func, time, ctx, immediate) => {
    let timer
    const rtn = (...params) => {
        clearTimeout(timer)
        if (immediate) {
            let callNow = !timer
            timer = setTimeout(() => {
                timer = null
            }, time)
            if (callNow) func.apply(ctx, params)
        } else {
            timer = setTimeout(() => {
                func.apply(ctx, params)
            }, time)
        }
    }
    return rtn
}

Vue.component('Debounce', {
    abstract: true,
    props: ['time', 'events', 'immediate'],//time 延迟时间   events绑定事件集合  immediate是否立即执行
    created() {
        this.eventKeys = this.events && this.events.split(',')
    },
    render() {
        const vnode = this.$slots.default[0]

        //原生dom绑定的事件集合为vnode.data.on    第三方element 绑定的事件集合componentOptions.listeners
        let eventsList = vnode.data.on || vnode.componentOptions.listeners
        // 如果默认没有传 events，则对所有绑定事件加上防抖
        if (!this.eventKeys) {
            this.eventKeys = Object.keys(eventsList)
        }
        this.eventKeys.forEach(key => {
            eventsList[key] = debounce(
                eventsList[key],
                this.time,
                vnode,
                this.immediate
            )
        })
        return vnode
    }
})